package test_312;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 张杰
 * Date: 2022-03-13
 * Time: 9:51
 */
/*
 * @param <T> 此时代表当前类是一个泛型类，T：当做是一个占位符
 * @return null
*/
class Alg<T extends Comparable<T>> {//特殊的上限
    public T findMax(T[] array) {
        T max = array[0];
        for (int i = 0; i < array.length; i++) {
            if(max.compareTo(array[i]) < 0) {//T[]是引用类型，不能直接比较大小，需要实现compare方法
                max = array[i];
            }
        }
        return max;
    }
}

class Alg2{
    //需要对static进行修饰限定
    public static<T extends Comparable<T>> T  findMax(T[] array) {//静态方法是依赖于对象的
        T max = array[0];
        for (int i = 1; i < array.length; i++) {
            if(max.compareTo(array[i]) < 0) {
                max = array[i];
            }
        }
        return max;
    }
}

class Alg3 {
    //可以确定参数类型是T
    public static <T> void print1(ArrayList<T> list) {
        for (T x:list) {
            System.out.println(x);
        }
    }
    //参数的类型未知(通配符)
    public static void print2(ArrayList<?> list) {
        for (Object x:list) {
            System.out.println(x);
        }
    }
}
class MyArray<T /*extends Number*/> {
    //public T[] objects = new T[10];//不能实例化泛型类型的数组
    //通过映射实现传递参数类型为T
    /*public T[] array;
    public MyArray(Class<T>clazz,int capacity) {
        array = (T[])Array.newInstance(clazz,capacity);
    }*/

    public T[] objects = (T[]) new Object[10];//编译的时候T会被替换成Object
    public void set(int pos,T val) {
        objects[pos] = val;
    }
    public T get(int pos) {
        return objects[pos];
    }
    public T[] getArray() {
        return objects;
    }
}

class Person {

}
class Student extends Person {

}

public class TestDemo {
    public static void main(String[] args) {
        ArrayList<? super Person> arrayList1 = new ArrayList<>();
        arrayList1.add(new Person());
        arrayList1.add(new Student());

        //Person person = arrayList1.get(0);
    }

    public static void main5(String[] args) {
        ArrayList<Integer> arrayList1 = new ArrayList<>();
        ArrayList<Double> arrayList2 = new ArrayList<>();
        List<? extends Number> list = arrayList1;//通配符可以实现父子类继承

        /*list.add(0,1);
        list.add(1,10.9);通配符的上界不适合写入数据，因为不清粗写入的数据类型比较适合读数据*/

        Number o =list.get(0);
    }
    public static void main4(String[] args) {
        Integer[] array = {1,12,3,4,16};
        System.out.println(Alg2.<Integer>findMax(array));
        System.out.println(Alg2.findMax(array));//也可以不写，可以通过推到得来

        Alg<Integer> alg1 = new Alg<Integer>();
        System.out.println(alg1);
        Alg<Integer> alg2 = new Alg<Integer>();
        System.out.println(alg2);
    }

    public static void main3(String[] args) {
        Alg<Integer> alg1 = new Alg<>();
        Integer[] arr = {12,34,3,26,19,36};
        System.out.println(alg1.findMax(arr));

        Alg<String> alg2 = new Alg<>();
        String[] arr2 = {"hell0","bit","world"};
        System.out.println(alg2.findMax(arr2));
    }
    public static void main2(String[] args) {
            MyArray<Integer> myArray = new MyArray<>();//String不是Number的子类
        //String[] ret = myArray.getArray();//编译器认为此时并不安全，返回值不一定是String类型的
        Object[] ret1 = myArray.getArray();//需要用Object来接收

        MyArray<Integer> myArray1 = new MyArray<>();
        MyArray<Number> myArray2 = new MyArray<>();

        ArrayList<Integer> arrayList = new ArrayList<>();
        arrayList.add(1);
        arrayList.add(2);
        Object[] ret2 = arrayList.toArray();
    }
    public static void main1(String[] args) {
        MyArray<String> myArray = new MyArray<>();
        myArray.set(0,"hello");
        //myArray.set(1,10);//编译的时候会自动检查，类型是否符合
        String str = myArray.get(0);//不需要进行类型的强制转换
        MyArray<Integer> myArray2 = new MyArray<>();//简单类型不能作为泛型类型的参数

        MyArray myArray3 = new MyArray();
        myArray3.set(0,"hello");
        myArray3.set(1,10);
        String str2 = (String)myArray3.get(0);
    }
}
